package ph.com.gs3.formalistics;

import java.util.List;

import org.json.JSONException;

import ph.com.gs3.formalistics.communicators.Communicator;
import ph.com.gs3.formalistics.communicators.DocumentCommunicatorModule;
import ph.com.gs3.formalistics.fragments.dialogs.DocumentActionsDialogFragment;
import ph.com.gs3.formalistics.fragments.views.DocumentViewFragment;
import ph.com.gs3.formalistics.fragments.workers.DocumentWorkerFragment;
import ph.com.gs3.formalistics.interfaces.CallbackCommand;
import ph.com.gs3.formalistics.managers.DocumentManager;
import ph.com.gs3.formalistics.model.dao.DocumentsDAO;
import ph.com.gs3.formalistics.model.dao.FormsDAO;
import ph.com.gs3.formalistics.model.valueobjects.application.Document;
import ph.com.gs3.formalistics.model.valueobjects.application.DocumentAction;
import ph.com.gs3.formalistics.model.valueobjects.application.Form;
import ph.com.gs3.formalistics.model.valueobjects.application.FormField.InvalidFormFieldException;
import ph.com.gs3.formalistics.utilities.FLLogger;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.Toast;

public class DocumentActivity extends Activity {

	public static final String TAG = DocumentActivity.class.getSimpleName();

	public static final String EXTRA_DOCUMENT_TYPE = "document_type";
	public static final String EXTRA_FORM_DB_ID = "form_db_id";
	public static final String EXTRA_DOCUMENT_DB_ID = "document_db_id";
	public static final String EXTRA_SERVER = "server";

	// dependencies
	private DocumentViewFragment documentViewFragment;
	private DocumentWorkerFragment documentWorkerFragment;

	private FormsDAO formsDAO;
	private DocumentsDAO documentsDAO;
	private DocumentCommunicatorModule documentCommModule;

	private DocumentManager documentManager;

	// data fields
	private String server;
	private String formDbId;
	private String documentDbId;
	private DocumentType documentType;

	private Form currentForm;
	private Document currentDocument;

	public static enum DocumentType {
		NEW_DOCUMENT, EXISTING_DOCUMENT, OUTGOING_DOCUMENT_ACTION
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_document);

		initializeFieldsFromExtras();
		initializeWorkerFragment();
		initializeDataFields();
		initializeManagers();

		if (savedInstanceState == null) {
			try {

				Form form = documentWorkerFragment.getForm();
				Document document = documentWorkerFragment.getDocument(documentDbId);

				documentViewFragment = DocumentViewFragment.createInstance(form, document);
				getFragmentManager().beginTransaction().add(R.id.container, documentViewFragment)
				        .commit();

				setTitle(form.getName());
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvalidFormFieldException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.document, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		switch (id) {
			case R.id.action_submit_action: {
				showActionsDialog();
				return true;
			}
		}

		return super.onOptionsItemSelected(item);
	}
		
	// ========================================================================
	// Functional Methods

	private void submitDocumentAction(String action) {

		// extract data from document view
		Document updatedDocument = documentViewFragment.updateDocumentValuesFromView();

		FLLogger.d(TAG, action);

		documentManager.submitDocumentAction(updatedDocument, action,
		        new CallbackCommand<DocumentManager.SubmitDocumentActionResult>() {

			        @Override
			        public void execute(DocumentManager.SubmitDocumentActionResult result) {

				        if (result.communicatorException != null) {
					        FLLogger.d(TAG, result.communicatorException.getMessage());
				        }

				        if (result.invalidResponseException != null) {
					        FLLogger.d(TAG, result.invalidResponseException.getMessage());
				        }

				        if (result.response != null) {
					        FLLogger.d(TAG, result.response.getResults());
				        }

			        }
		        });

	}

	// ========================================================================
	// Dialog View Methods

	private void showActionsDialog() {

		DocumentActionsDialogFragment dialog = new DocumentActionsDialogFragment();
		List<DocumentAction> actions;

		if (documentType == DocumentType.NEW_DOCUMENT) {
			actions = currentForm.getActions();
		} else {
			return;
		}

		dialog.setActions(actions);
		dialog.show(getFragmentManager(), DocumentActionsDialogFragment.TAG);
		dialog.setOnActionSelectedCallback(new CallbackCommand<DocumentAction>() {

			@Override
			public void execute(DocumentAction clickedAction) {
				// submitDocumentAction(clickedAction.getAction());
				submitDocumentAction(clickedAction.getLabel());
			}
		});
	}

	// ========================================================================
	// Initializer Methods

	private void initializeFieldsFromExtras() {

		Bundle extras = getIntent().getExtras();

		server = extras.getString(EXTRA_SERVER);

		documentType = (DocumentType) extras.get(EXTRA_DOCUMENT_TYPE);
		formDbId = extras.getString(EXTRA_FORM_DB_ID);
		documentDbId = extras.getString(EXTRA_DOCUMENT_DB_ID);

	}

	private void initializeWorkerFragment() {

		// initialize the worker fragment dependencies

		Communicator communicator = new Communicator();

		formsDAO = new FormsDAO(getApplicationContext());
		documentsDAO = new DocumentsDAO(getApplicationContext());

		documentCommModule = new DocumentCommunicatorModule(communicator, server);

		documentWorkerFragment = DocumentWorkerFragment.createInstance(formsDAO, documentsDAO,
		        documentCommModule, formDbId);

	}

	private void initializeDataFields() {

		formsDAO.open();
		try {
			currentForm = formsDAO.getForm(formDbId);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidFormFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			formsDAO.close();
		}

	}

	private void initializeManagers() {

		documentManager = new DocumentManager(documentsDAO, documentCommModule);

	}
}
